package cn.zero.letaomallspringboot.filter;

import cn.zero.letaomallspringboot.Constant.ResultCode;
import cn.zero.letaomallspringboot.common.JwtUtil;
import com.fasterxml.jackson.databind.ObjectMapper;
import jakarta.servlet.FilterChain;
import jakarta.servlet.ServletException;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import org.springframework.http.MediaType;
import org.springframework.util.AntPathMatcher;
import org.springframework.web.filter.OncePerRequestFilter;

import java.io.IOException;
import java.util.HashMap;
import java.util.Map;

public class JwtAuthenticationFilter extends OncePerRequestFilter {

    private final AntPathMatcher pathMatcher = new AntPathMatcher();

    @Override
    protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain)
            throws ServletException, IOException {
        String requestUri = request.getRequestURI();
        String method = request.getMethod();

        // 1. 优先放行 OPTIONS 预检请求
        if ("OPTIONS".equals(method)) {
            filterChain.doFilter(request, response);
            return;
        }

        // 2. 放行 Swagger UI 相关路径（Swagger 3.0）
        if (isSwaggerPath(requestUri)) {
            filterChain.doFilter(request, response);
            return;
        }

        // 3. 放行 login 接口
        if (pathMatcher.match("/admin/login", requestUri)) {
            filterChain.doFilter(request, response);
            return;
        }

        // 4. 验证 token
        String token = request.getHeader("Authorization");
        if (token == null || !token.startsWith("Bearer ")) {
            sendUnauthorizedResponse(response);
            return;
        }

        // 提取 token
        token = token.substring(7);

        // 检查 JWT 有效性
        if (JwtUtil.getUserIdByToken(token) != null && !JwtUtil.isTokenExpired(token)) {
            // token 有效，继续执行
            request.setAttribute("userId", JwtUtil.getUserIdByToken(token));
            filterChain.doFilter(request, response);
            return;
        }

        // JWT 无效
        sendUnauthorizedResponse(response);
    }

    /**
     * 判断是否为 Swagger 相关路径（适配 Swagger 3.0）
     */
    private boolean isSwaggerPath(String requestUri) {
        // Swagger UI 页面及静态资源
        if (pathMatcher.match("/swagger-ui/**", requestUri) ||
                pathMatcher.match("/swagger-ui/index.html", requestUri)) {
            return true;
        }
        // OpenAPI 接口文档数据（Swagger 内部调用）
        if (pathMatcher.match("/v3/api-docs/**", requestUri) ||
                pathMatcher.match("/v3/api-docs.yaml", requestUri)) {
            return true;
        }
        return false;
    }

    /**
     * 发送未授权响应（手动添加 CORS 头）
     */
    private void sendUnauthorizedResponse(HttpServletResponse response) throws IOException {
        // 手动设置 CORS 头
        response.setHeader("Access-Control-Allow-Origin", "http://localhost:5173");
        response.setHeader("Access-Control-Allow-Methods", "GET, POST, PUT, DELETE, OPTIONS");
        response.setHeader("Access-Control-Allow-Headers", "*");
        response.setHeader("Access-Control-Allow-Credentials", "true");

        response.setStatus(HttpServletResponse.SC_UNAUTHORIZED);
        response.setContentType(MediaType.APPLICATION_JSON_VALUE);
        Map<String, Object> error = new HashMap<>();
        error.put("success", false);
        error.put("code", ResultCode.UNAUTHORIZED.getCode());
        error.put("msg", ResultCode.UNAUTHORIZED.getMsg());
        new ObjectMapper().writeValue(response.getWriter(), error);
    }
}
